import * as Field from './../fields';
import defaultConfig from './defaults';
import {
    mergeObject,
    throttle,
    deepCopy,
    getKeyboardDir,
    getScrollbarWidth,
} from './../utils';
import {
    createScrollBarTd,
    createTemplateTd,
    createTemplateTr,
    createTemplateHeader,
    createTemplateBody,
    createTemplateFooter,
    createTemplateFixed,
    createTemplateRightPatch,
} from './template';

/**
 * 表格类（核心主类）
 */

export default class Table {
    constructor(options) {
        this.options = mergeObject(options, defaultConfig);
        this.init();
        this.render();
        this.bindEvent();
        this.burstProcessing();
        console.log(this);
    }
    // 初始化
    init(data) {
        let { el, fields, event, config } = this.options;
        // 深拷贝数据
        data = deepCopy(data || this.options.data);
        // 基础参数
        this.data = data.slice(0, config.burstSize);
        this.event = event;
        this.fields = fields;
        this.config = config;
        config.data = data;
        // 是否分片处理
        this.isBurst = data.length > config.burstSize;
        // 关键dom对象
        this.$body = $('body');
        this.$container = $(el);
        // 合计参数
        this.summaryData = {};
        this.showSummary = config.showSummary;
        // scrollbar设置
        this.scrollbarDisplay = 'none';
        this.scrollbarWidth = getScrollbarWidth();
        // td高度参数
        this.headerTdHeight = config.headerTdHeight;
        this.bodyTdHeight = config.bodyTdHeight;
        this.footerTdHeight = config.footerTdHeight;
        // 容器宽高
        this.containerWidth = config.width || this.$container.width();
        this.containerHeight = 0;
        // 当前下拉参数
        this.selectPoint = {};
        this.autocomplePoint = {};
        this.currentSelect = null;
        this.currentAutocomple = null;
        this.$selectBox = null;
        this.$autocompleteBox = null;
        this.isHaveBox = false;
        // 右侧栏设置
        this.$fixed = null;
        this.fixedLeft = 0;
        this.fixedWidth = 0;
        // 字段列表
        this.fieldList = [];
        // 事件绑定句柄
        this.mousewheelMethod = null;
        this.tableScrollMethod = null;
        this.clickMethod = null;
        // 游览器判断
        this.isFirefox = navigator.userAgent.indexOf("Firefox");
    }
    // 渲染
    render() {
        // 创建ScrollBarTd
        const scrollBarTd = this.createScrollBarTd();
        // 创建表体结构
        const bodyTemplate = this.createBody();
        // 创建表头/表尾结构
        const headerTds = [];
        const footerTds = [];
        this.fields.forEach(field => {
            headerTds.push(this.createContentTd(field, 'header'));
            footerTds.push(this.createContentTd(field, 'footer'));
        });
        const headerTemplate = this.createHeader(scrollBarTd, headerTds);
        const footerTemplate = this.createFooter(scrollBarTd, footerTds);
        // 生成表格结构
        this.$tableHeader = $(headerTemplate);
        this.$tableBody = $(bodyTemplate);
        this.$tableFooter = $(footerTemplate);
        this.$container.append(this.$tableHeader);
        this.$container.append(this.$tableBody);
        if (this.showSummary) this.$container.append(this.$tableFooter);
        // 保证容器为相对定位
        this.$container.addClass('ddmg_edit_table');
        // 生成fixed侧栏
        this.createFixedColumn(headerTemplate + bodyTemplate + footerTemplate);
        // 设置fixed侧栏状态（位置和高度）
        this.updateFixedState();
    }
    // 分片处理
    burstProcessing() {
        if (this.isBurst) {
            const { data, burstSize } = this.config;
            const allCount = data.length;
            const startIndex = burstSize;
            const loop = (curTotal, curIndex) => {
                if (curTotal <= 0) {
                    this.isBurst = false;
                    this.updateSummaryData();
                    return;
                };
                let pageCount = Math.min(curTotal, burstSize);
                window.requestAnimationFrame(() => {
                    let addIndex = 0;
                    for (let i = 0; i < pageCount; i++) {
                        addIndex = curIndex + i;
                        if (addIndex < allCount) this.addRow(data[addIndex], addIndex - 1);
                    }
                    if (addIndex < allCount) loop(curTotal - pageCount, curIndex + pageCount);
                })
            }
            loop(allCount - burstSize, startIndex);
        } else {
            this.updateSummaryData();
        }
    }
    // 创建fixed栏
    createFixedColumn(template) {
        const fixedField = this.fields[this.fields.length - 1];
        if (fixedField.fixed) {
            // 设置控制列宽度值
            this.setControlColWidthValue();
            // 生成fixed栏结构
            const fixedTemplate = this.createFixed(template, this.fixedWidth);
            this.$fixed = $(fixedTemplate);
            this.$container.append(this.$fixed);
            // 设置fixed位置
            if (fixedField.fixed === 'right') this.updateFixedSite();
            // 子级设置（清除子级宽度）
            const fixedHeaderEl = this.$fixed.find('.ddmg_header_table').get(0);
            const fixedBodyEl = this.$fixed.find('.ddmg_body_table').get(0);
            const fixedFooterEl = this.$fixed.find('.ddmg_footer_table').get(0);
            // const fixedColEl = this.$fixed.find('.control').get(0);
            // 去除fixed表格模板受影响的样式
            fixedHeaderEl.removeAttribute('style');
            fixedBodyEl.removeAttribute('style');
            fixedFooterEl.removeAttribute('style');
            // 设置fixedBody表格与fixedHeader的顶部间距
            // （方案1：该方案存在兼容性问题，无性能损失，但是准确性低）
            // fixedBodyEl.style.top = this.headerTdHeight + 2.2 + 'px';
            // （方案2：存在回流问题，性能损失200~300毫秒，但是准确性高）
            fixedBodyEl.style.top = fixedHeaderEl.offsetHeight + 'px';
            // 设置控制列宽度
            this.$fixed.find('.control').width(this.fixedWidth);
            // right-patch设置（滚动条显示垫片）
            const rightPatchTemplate = createTemplateRightPatch(this.scrollbarWidth, this.headerTdHeight);
            this.$container.append(rightPatchTemplate + (this.showSummary ? rightPatchTemplate : ''));
            // 如果非合计
            if (this.showSummary === false) this.$fixed.find('.ddmg_footer_table').remove();
        }
    }
    // 设置控制列实际宽度
    setControlColWidthValue() {
        this.fixedWidth = this.$tableHeader.find('.control').width();
    }
    // 插行
    insertRow(rowData, rowIndex = this.data.length - 1) {
        this.addRow(rowData, rowIndex);
        this.event.onInsertRow(rowIndex);
    }
    // 复制
    copyRow(rowIndex) {
        this.addRow(deepCopy(this.data[rowIndex]), rowIndex);
        this.event.onCopyRow(rowIndex);
    }
    // 增加
    addRow(rowItem, rowIndex) {
        // 加入位置
        const addSite = rowIndex + 1;
        // 更新字段列表
        const fieldRow = this.createFieldRow(rowItem, addSite);
        this.fieldList.splice(addSite, 0, fieldRow);
        // 更新数据列表
        this.data.splice(addSite, 0, rowItem);
        // 生成行模板
        const tds = this.createTds(fieldRow, 'body');
        const tr = this.createTr(tds);
        // 更新dom
        const $tr = $(tr);
        const $lastTr = this.$tableBody.find('tr').eq(rowIndex);
        $lastTr.after($tr);
        this.$fixed && this.$fixed.find('.ddmg_body_table tr').eq(rowIndex).after(tr);
        // 事件绑定
        this.bindFieldEvent(fieldRow, $tr);
        // 更新字段行号
        this.updateFieldSiteIndex();
        // 更新合计行
        this.updateSummaryData();
        // 更新fixed栏状态
        this.updateFixedState();
    }
    // 删除
    deleteRow(rowIndex) {
        // 触发删除钩子
        const status = this.event.onDeleteRow(rowIndex);
        if (status === false) return;
        // 更新字段列表
        this.fieldList.splice(rowIndex, 1);
        // 更新数据列表
        this.data.splice(rowIndex, 1);
        // 更新dom
        this.$tableBody.find('tr').eq(rowIndex).remove();
        this.$fixed && this.$fixed.find('.ddmg_body_table tr').eq(rowIndex).remove();
        // 更新字段行号
        this.updateFieldSiteIndex();
        // 更新合计行
        this.updateSummaryData();
        // 更新fixed栏状态
        this.updateFixedState();
        console.log('deleteRow', this);
    }
    // 创建scrollbarTd
    createScrollBarTd() {
        const width = this.scrollbarWidth;
        return createScrollBarTd(width);
    }
    // 创建内容td
    createContentTd(field, tdType = 'body') {
        let value, height;
        if (tdType === 'header') {
            const star = field.validate ? '<i>*</i>' : '';
            value = star + field.label;
            height = this.headerTdHeight;
        } else if (tdType === 'body') {
            value = field.create();
            height = this.bodyTdHeight;
        } else if (tdType === 'footer') {
            value = '&nbsp;';
            height = this.footerTdHeight;
        }
        const { type, width, align, headerAlign } = field;
        const td = this.createTd({ value, type, width, height, align, headerAlign }, tdType);
        return td;
    }
    // 创建td单元
    createTd() {
        return createTemplateTd(...arguments);
    }
    // 创建tds集合
    createTds(fieldRow, type) {
        return fieldRow.map(field => {
            return this.createContentTd(field, type);
        });
    }
    // 创建tr单元
    createTr(tds) {
        return createTemplateTr(tds);
    }
    // 创建trs集合
    createTrs(fieldList, type) {
        return fieldList.map(fieldRow => {
            const tds = this.createTds(fieldRow, type);
            const tr = this.createTr(tds);
            return tr;
        });
    }
    // 创建表头
    createHeader(scrollBarTd, tds) {
        const tr = this.createTr(tds.concat(scrollBarTd));
        return createTemplateHeader(tr, this.config);
    }
    // 创建表体
    createBody() {
        const trs = [];
        this.data.forEach((item, index) => {
            const fieldRow = this.createFieldRow(item, index);
            const tds = this.createTds(fieldRow, 'body');
            const tr = this.createTr(tds);
            trs.push(tr);
            this.fieldList.push(fieldRow);
        });
        return createTemplateBody(trs, this.config);
    }
    // 创建表尾
    createFooter(scrollBarTd, tds) {
        const tr = this.createTr(tds.concat(scrollBarTd));
        return createTemplateFooter(tr, this.config);
    }
    // 创建fixed
    createFixed(...args) {
        return createTemplateFixed(...args);
    }
    // 创建字段行
    createFieldRow(rowItem, rowIndex) {
        return this.fields.map((field, colIndex) => {
            const addProps = { 
                value: rowItem[field.prop],
                rowIndex, 
                colIndex, 
                table: this 
            };
            const params = { ...field, ...addProps };
            return new Field[field.type](params);
        });
    }
    // 更新字段位置属性
    updateFieldSiteIndex() {
        this.fieldList.forEach((fieldRow, rowIndex) => {
            fieldRow.forEach((field, colIndex) => {
                field.rowIndex = rowIndex;
                field.colIndex = colIndex;
                field.$el.attr({ rowIndex, colIndex });
                if (field.type == 'count') field.$el.text(rowIndex + 1);
            })
        });
    }
    // 更新fixed栏表格位置
    updateFixedSite() {
        if (this.$fixed) {
            const width = this.config.width || this.$container.get(0).offsetWidth;
            this.fixedLeft = width - this.fixedWidth + 1;
            this.$fixed.css('left', this.fixedLeft);
        }
    }
    // 更新fixed栏和rightPatch垫片结构的偏移
    updateFixedExc(scrollbarDisplay = this.scrollbarDisplay) {
        if (this.$fixed) {
            const fixedEl = this.$fixed.get(0);
            const positionLeft = this.fixedLeft;
            const rightPatchTop = fixedEl.nextElementSibling;
            const rightPatchBottom = rightPatchTop.nextElementSibling;
            const scrollbarWidth = this.scrollbarWidth;
            if (scrollbarDisplay === 'none') {
                // 更新fixed栏位置
                fixedEl.style.left = positionLeft + 'px';
                // 显示垫片结构-显示隐藏
                rightPatchTop.style.display = 'none';
                if (rightPatchBottom) rightPatchBottom.style.display = 'none';
                // 显示垫片结构-移除边框线（弥补显示问题）
                $(rightPatchTop).removeClass('border');
                if (rightPatchBottom) $(rightPatchBottom).removeClass('border');
            } else {
                // 更新fixed栏位置
                fixedEl.style.left = positionLeft - scrollbarWidth + 'px';
                // 显示垫片结构-显示隐藏
                rightPatchTop.style.display = 'block';
                if (rightPatchBottom) rightPatchBottom.style.display = 'block';
                // 显示垫片结构-位置更新
                const siteValue = positionLeft + this.fixedWidth - scrollbarWidth + 'px';
                rightPatchTop.style.left = siteValue;
                if (rightPatchBottom) rightPatchBottom.style.left = siteValue;
                // 显示垫片结构-增加边框线（弥补显示问题）
                $(rightPatchTop).addClass('border');
                if (rightPatchBottom) $(rightPatchBottom).addClass('border');
            }
        }
    }
    // 更新fixed栏表格状态
    updateFixedState() {
        const scrollbarWidth = this.scrollbarWidth;
        const bodyHeight = this.config.height;
        const contentHeight = this.bodyTdHeight * this.data.length;
        const styleValue = bodyHeight ? (contentHeight > bodyHeight ? 'table-cell' : 'none') : 'none';
        // 更新容器高度
        const updateContainerHeight = () => {
            const headerTdHeight = this.headerTdHeight;
            const footerHeight = this.showSummary ? this.footerTdHeight : 0;
            const _bodyHeight = bodyHeight ? bodyHeight : contentHeight;
            this.containerHeight = headerTdHeight + footerHeight + _bodyHeight;
        }
        // 更新fixed栏高度
        const updateFixedHeight = () => {
            if (this.$fixed) {
                const tableBodyEl = this.$tableBody.get(0);
                const visibleScrollBar = tableBodyEl.scrollWidth <= tableBodyEl.clientWidth;
                const _scrollbarWidth = visibleScrollBar ? 0 : scrollbarWidth;
                const realBodyHeight = this.data.length * this.bodyTdHeight + _scrollbarWidth - (this.isFirefox ? 1 : 5);
                const fixedEl = this.$fixed.get(0);
                const fixedBodyEl = this.$fixed.find('.ddmg_body_table').get(0);
                const headerHeight = this.headerTdHeight;
                const bodyHieght = this.config.height || realBodyHeight;
                const footerHeight = this.showSummary ? this.footerTdHeight : 0;
                fixedEl.style.height = headerHeight + bodyHieght + footerHeight + 2 + 'px';
                fixedBodyEl.style.height = bodyHieght - _scrollbarWidth + 'px';
            }
        }
        // 更新scrollbar列显示与否
        if (this.scrollbarDisplay !== styleValue) {
            const scrollbarTdEl = this.$tableHeader.find('.scrollbar_td').get(0);
            scrollbarTdEl.style.display = styleValue;
            if (this.showSummary) this.$tableFooter.find('.scrollbar_td').get(0).style.display = styleValue;
            this.updateFixedExc(styleValue);
        }
        updateFixedHeight();
        updateContainerHeight();
        this.scrollbarDisplay = styleValue;
    }
    // 更新合计数据
    updateSummaryData() {
        if (this.isBurst || !this.showSummary) return;
        // 重置合计数据
        this.fields.forEach(item => {
            this.summaryData[item.prop] = 0;
        })
        // 设置合计数据
        this.fieldList.forEach((fieldRow) => {
            fieldRow.forEach((field) => {
                this.summaryData[field.prop] += field.value * 1;
            })
        });
        // 更新合计数据
        const summaryMethod = this.config.summaryMethod;
        this.summaryData = summaryMethod && summaryMethod(deepCopy(this.summaryData)) || this.summaryData;
        // 更新合计dom
        this.fields.forEach((field, colIndex) => {
            if (['text', 'input'].indexOf(field.type) >= 0) {
                let value = this.summaryData[field.prop];
                value = value ? value : (value == 0 ? 0 : '');
                this.$tableFooter.find('td').eq(colIndex).text(value);
            }
        })
    }
    // 更新下拉位置
    updateSelectSite(closeSelect) {
        // 保持select下拉位置
        if (this.currentSelect && this.currentSelect.listVisible) {
            const { left, top, scrollLeft, scrollTop, curScrollLeft = 0, curScrollTop = 0 } = this.selectPoint;
            const selectLeft = left + curScrollLeft - scrollLeft;
            const selectTop = top + curScrollTop - scrollTop;
            this.$selectBox.css({
                left: selectLeft,
                top: selectTop
            });
            if (selectTop < 0 || selectTop > this.containerHeight) closeSelect(false, true);
        }
        // 保持autocomple下拉位置
        if (this.currentAutocomple && this.currentAutocomple.listVisible) {
            const { left, top, scrollLeft, scrollTop, curScrollLeft = 0, curScrollTop = 0 } = this.autocomplePoint;
            const autocompleteLeft = left + curScrollLeft - scrollLeft;
            const autocompleteTop = top + curScrollTop - scrollTop;
            this.$autocompleteBox.css({
                left: autocompleteLeft,
                top: autocompleteTop
            });
            if (selectTop < 0 || selectTop > this.containerHeight) closeSelect(true, false);
        }
    }
    // 绑定事件
    bindEvent() {
        const headerEl = this.$tableHeader.get(0);
        const bodyEl = this.$tableBody.get(0);
        const footerEl = this.$tableFooter && this.$tableFooter.get(0);
        const rightBodyEl = this.$fixed && this.$fixed.find('.ddmg_body_table table').get(0);
        const containerEl = this.$container.get(0);
        const wheelDistance = this.isFirefox >= 0 ? 1 : 5;
        const closeSelect = (visibleAutocomple = true, visibleSelect = true) => {
            const isCloseAutocomple = visibleAutocomple && this.currentAutocomple && this.currentAutocomple.listVisible;
            const isCloseSelect = visibleSelect && this.currentSelect && this.currentSelect.listVisible;
            isCloseAutocomple && this.currentAutocomple.closeAutocompleteList();
            isCloseSelect && this.currentSelect.closeSelectList().recoverSelectName();
        }
        this.mousewheelMethod = (event, data) => {
            // const isFixed = $(event.target).parents('.ddmg_fixed_table')[0];
            // if (isFixed) bodyEl.scrollTop += Math.ceil(data.pixelY / 5);
            if (this.config.height && event.target.nodeName !== 'LI') {
                bodyEl.scrollTop += Math.ceil(data.pixelY / wheelDistance);
            }
        }
        this.tableScrollMethod = (event) => {
            const { scrollLeft, scrollTop } = event.target;
            // 记录table滚动位置
            this.selectPoint.scrollLeft = scrollLeft;
            this.selectPoint.scrollTop = scrollTop;
            this.autocomplePoint.scrollLeft = scrollLeft;
            this.autocomplePoint.scrollTop = scrollTop;
            // 保持其他表格位置
            headerEl.scrollLeft = scrollLeft;
            if (this.showSummary) footerEl.scrollLeft = scrollLeft;
            if (rightBodyEl) rightBodyEl.style.webkitTransform = `translate3d(0, ${ -scrollTop }px, 0)`;
            // 保持下拉位置
            this.updateSelectSite(closeSelect);
        }
        this.clickMethod = (event) => {
            const isEditTable = $(event.target).closest('.ddmg_edit_table').length > 0;
            // 点击表格
            if (isEditTable) {
                const element = event.target;
                const parentEl = element.parentNode;
                const className = element.className;
                const rowIndex = $(element).closest('tr').index();
                const isSelect = parentEl.className.indexOf('select_div') >= 0;
                const isAutocomplete = parentEl.className.indexOf('autocomplete_div') >= 0;
                const isSelectBox = $(element).closest('.ddmg_select_box').length > 0;
                const isAutocompleteBox = $(element).closest('.ddmg_autocomplete_box').length > 0;
                // control列处理
                if (['copy', 'delete'].indexOf(className) >= 0) {
                    const colIndex = this.fields.length - 1;
                    this.fieldList[rowIndex][colIndex].eventProcessing(className);
                }
                // select和autocomplete列处理
                if (isSelect || isAutocomplete) {
                    const colIndex = parentEl.getAttribute('colIndex');
                    // 清空处理
                    if (className === 'clear') {
                        this.fieldList[rowIndex][colIndex].eventProcessing('clear', element);
                    } else {
                        this.fieldList[rowIndex][colIndex].eventProcessing('click');
                    }
                    // 关闭处理
                    if (isSelect) closeSelect(true, false);
                    if (isAutocomplete) closeSelect(false, true);
                } else if (element.nodeName === 'LI') {
                    // select下拉点击处理
                    if (isSelectBox && this.currentSelect) this.currentSelect.eventProcessing('check', element);
                    // autocomplete下拉点击处理
                    if (isAutocompleteBox && this.currentAutocomple) this.currentAutocomple.eventProcessing('check', element);
                } else {
                    // 关闭下拉
                    closeSelect();
                }
                // 触发行点击钩子函数
                this.event.onClickRow(rowIndex);
            } else {
                // 关闭下拉
                closeSelect();
            }
            event.stopPropagation();
        }
        this.keyupMethod = (event) => {
            const direction = getKeyboardDir(event);
            const currentSelect = this.currentSelect;
            const currentAutocomple = this.currentAutocomple;
            currentSelect && currentSelect.dropDownProcessing(direction);
            currentAutocomple && currentAutocomple.dropDownProcessing(direction);
        }
        // 表格滚轮绑定
        if (rightBodyEl) containerEl.onMousewheel(this.mousewheelMethod);
        // 表格滚动绑定
        bodyEl.addEventListener('scroll', this.tableScrollMethod);
        // 表格点击绑定（mouseup可以监听到滚动条点击，click不行）
        document.addEventListener('mousedown', this.clickMethod);
        // 表格键盘绑定
        document.addEventListener('keyup', this.keyupMethod);
        // 视口变化绑定
        window.onresize = throttle(() => {
            this.updateFixedState();
            this.updateFixedSite();
            this.updateFixedExc();
        }, 20);
        // 字段事件绑定
        const $trs = this.$tableBody.find('tr');
        this.fieldList.forEach((fieldRow, rowIndex) => {
            this.bindFieldEvent(fieldRow, $trs.eq(rowIndex));
        })
    }
    // 字段事件绑定
    bindFieldEvent(fieldRow, $tr) {
        fieldRow.forEach((field, colIndex) => {
            field.$el = $tr.find(`[colIndex="${colIndex}"]`);
            field.bindEvent();
        })
    }
    // 解绑事件
    removeEvent() {
        const bodyEl = this.$tableBody.get(0);
        const containerEl = this.$container.get(0);
        // 销毁滚轮事件
        if (this.$fixed) containerEl.onMousewheel('remove', this.mousewheelMethod);
        // 销毁表格滚动事件
        bodyEl.removeEventListener('scroll', this.tableScrollMethod);
        // 销毁点击事件
        document.removeEventListener('mousedown', this.clickMethod);
        // 销毁表格键盘事件
        document.removeEventListener('keyup', this.keyupMethod);
        // 视口变化绑定
        window.onresize = null;
        // 销毁字段事件
        this.removeFieldEvent();
    }
    // 字段事件绑定和引用
    removeFieldEvent() {
        this.fieldList.forEach((fieldRow, rowIndex) => {
            fieldRow.forEach((field, colIndex) => {
                field.removeEvent();
                for (const key in field) {
                    if (Object.hasOwnProperty.call(field, key)) {
                        field[key] = null;
                    }
                }
            })
        })
    }
    // 获取单行数据
    getRowData(rowlist) {
        if (typeof rowlist === 'number') {
            rowlist = [rowlist];
        }
        return rowlist.map(rowIndex => {
            return deepCopy(this.data[rowIndex]);
        });
    }
    // 获取所有数据
    getAllData() {
        return deepCopy(this.data);
    }
    // 禁用单项
    disabledItem(rowIndex, colIndex, isDisabled = true) {
        this.updateItemAction((fieldItem)=> {
            fieldItem.disabledItem(isDisabled);
        }, rowIndex, colIndex);
    }
    // 禁用单列
    disabledCol(colIndex, isDisabled = true) {
        this.updateColAction((fieldItem)=> {
            fieldItem.disabledItem(isDisabled);
        }, colIndex);
    }
    // 更新单项数据
    updateItemData(rowIndex, colIndex, value) {
        this.updateItemAction((fieldItem)=> {
            fieldItem.updateItemData(value);
            this.updateSummaryData();
        }, rowIndex, colIndex);
    }
    // 更新单列数据
    updateColData(colIndex, value) {
        this.updateColAction((fieldItem)=> {
            fieldItem.updateItemData(value);
            this.updateSummaryData();
        }, colIndex);
    }
    // 更新单列下拉数据
    updateColItems(colIndex, items) {
        this.updateColAction((fieldItem)=> {
            fieldItem.items = items;
        }, colIndex);
    }
    // 更新单项动作
    updateItemAction(callback, rowIndex, colIndex) {
        if (String(Number(colIndex)) === 'NaN') {
            const fieldRows = this.fieldList[rowIndex];
            fieldRows ? fieldRows.forEach(fieldItem => {
                if (fieldItem.prop == colIndex) {
                    callback(fieldItem);
                }
            }) : this.throwError('未找到该项');
        } else {
            const fieldItem = this.fieldList[rowIndex][colIndex];
            fieldItem ? callback(fieldItem) : this.throwError('未找到该项');
        }
    }
    // 更新单列动作
    updateColAction(callback, colIndex) {
        if (String(Number(colIndex)) === 'NaN') {
            this.fieldList.forEach(fieldRow => {
                fieldRow.forEach(fieldItem => {
                    if (fieldItem.prop == colIndex) {
                        callback(fieldItem);
                    }
                })
            })
        } else {
            this.fieldList.forEach(fieldRow => {
                const fieldItem = fieldRow[colIndex];
                fieldItem ? callback(fieldItem) : this.throwError('未找到该列');
            })
        }
    }
    // 更新全部数据
    updateAllData(data = []) {
        this.destroy();
        this.init(data);
        this.render();
        this.bindEvent();
        this.burstProcessing();
    }
    // 数据验证
    validate(callback = () => { }) {
        const rows = this.fieldList.map((fieldRow) => {
            const cols = fieldRow.map(field => {
                if (field.validate) {
                    return field.validate.verification(field.value);
                } else {
                    return Promise.resolve();
                }
            })
            return Promise.all(cols);
        });
        return new Promise((resolve, reject) => {
            Promise.all(rows).then(() => {
                resolve(true);
                callback(true);
            }).catch(() => {
                reject(false);
                callback(false);
            });
        });
    }
    // 销毁实例
    destroy() {
        this.removeEvent();
        // 销毁下拉
        this.$selectBox && this.$selectBox.remove();
        // 销毁下拉
        this.$autocompleteBox && this.$autocompleteBox.remove();
        // 销毁表格
        this.$container.empty();
    }
    // 抛出错误
    throwError(text) {
        throw new Error(text);
    }
}